/**
 * Copyright (C) 2012 Foxit Corporation.
 * All Rights Reserved.
 *
 * The following code is copyrighted and contains proprietary information and trade secrets of Foxit Corporation.
 * You can only redistribute files listed below to customers of your application, under a written SDK license agreement with Foxit.
 * You cannot distribute any part of the SDK to general public, even with a SDK license agreement.
 * Without SDK license agreement, you cannot redistribute anything.
 *
 * @file	fpdfreflow.h
 * @brief	Header file for the PDF Reflow module.
 * @details	The reflow module mainly offers the following functions:
 *			1. Rearrange the content of parsed PDF pages.
 *			2. Reparse PDF pages, which have been already parsed, according to the user's required page size.
 *			3. Render the parsed reflow-page to DIBitmap.
 *			4. Get data and coordinate values pointing to the current reading position.
 * @note	If you want to purchase Foxit PDF SDK license and use ANY of the following functions, please
 *			request for enabling PDF object module explicitly.
 */
  
 /** 
 * @addtogroup FGSPDFREFLOW PDF Reflow
 * @brief Methods in this module are included in fpdfreflow.h 
 */
/** @{*/
#ifndef __FGSPDFREFLOW__
#define __FGSPDFREFLOW__

#ifndef __FGSPDFBASE__
    #include "fpdfbase.h"
#endif

#ifdef __cplusplus
extern "C" {
#endif

/**
 * @defined __FGSPDFReflowPage
 * @abstract FGSPDF reflow page.
 */
typedef const struct __FGSPDFReflowPage * FGSPDFReflowPageRef;
    
/**
 * @brief Create a reflow page reference.
 *
 * @return	The new reflow page reference.
 * 
 */
FGSPDFReflowPageRef FGSPDFReflowCreatePage();

/**
 * @brief Destroy a reflow page reference.
 *
 * @param[in] page	Reference to a reflow page object.
 *
 * @return ::kFGSErrorSuccess means successfully.<br>
 *			For more definitions please see enum definitions <b>FGSErrorRet</b>.
 */
FGSErrorRet FGSPDFReflowDestroyPage(FGSPDFReflowPageRef page);
    
/**
 * @brief Get the size of a reflow page.
 *
 * @param[in] page					Reference to a reflow page object.
 * 
 * @return	The size of a reflow page.
 * 
 */
CGSize FGSPDFReflowGetPageSize(FGSPDFReflowPageRef page);
    
/**
 * @brief Set line space before parse page
 *
 * @param[in] page					Reference to a Reflowed page object.
 * @param[in] lineSpace				default value: 0
 *
 * @return ::kFGSErrorSuccess means successfully.<br>
 *			For more definitions please see enum definitions <b>FGSErrorRet</b>.
*/
FGSErrorRet FGSPDFReflowSetLineSpace(FGSPDFReflowPageRef page, Float32 lineSpace);
  
/** 
 * @name FGSPDFREFLOW Enumeration Types
 */
/**@{*/
/**
 * @brief FGSPDF Parse Flags
 */
enum {
    /** @ Whether to parse images. */
    kFGSPDFParserImage              = 0x1,
    /** @ Whether to slice images or texts for the page. */ 
    kFGSPDFParserPageMode           = 0x4,
};
/** @brief Alias of enumeration for parse flags. */
typedef UInt32 FGSPDFParserFlags;
/**@}*/

/**
 * @brief Start parsing a loaded PDF page into a reflow page
 *
 * @details Page Reflowing is a progressive process. It might take a long time to reflow
 *			a page. If the parameter <i>pause</i> parameter is provided, this function may return
 *			::kFGSErrorToBecontinued any time during reflowing.<br>
 *			When ::kFGSErrorToBecontinued is returned, the reflowing is not finished. The
 *			application must call ::FGSPDFReflowContinueParse to continue reflowing.
 *
 * @param[in] page					Reference to a reflow page object returned by createPage function.
 * @param[in] pdfPage				Reference to a PDF page object.
 * @param[in] width					The desired page width. This value should be above 20.
 * @param[in] fitPageHeight			The desired page height.
 * @param[in] pause					Pointer to a structure that can pause the rendering process.
 *									Can be NULL if no pausing is needed.
 *									If provided, this pointer has to be valid during the whole reflowing.
 * @param[in] flags					The parser flag. See macro definitions <b>FPDF_PARSER_xxx</b>.
 *
 * @return	::kFGSErrorSuccess means successfully.<br>
 *			For more definitions please see enum definitions <b>FGSErrorRet</b>.
 */
FGSErrorRet FGSPDFReflowStartParse(FGSPDFReflowPageRef page, FGSPDFPageRef  pdfPage, Float32 width, Float32 fitPageHeight, FGSPause *pause, FGSPDFParserFlags flags);

/**
 * @brief Continue parsing a reflow page
 *
 * @param[in] page					Reference to a reflow page object used in startParse function.
 *
 * @return	::kFGSErrorSuccess means successfully.<br>
 *			For more definitions please see enum definitions <b>FGSErrorRet</b>.
 *
 */
FGSErrorRet	FGSPDFReflowContinueParse(FGSPDFReflowPageRef page);

/**
 * @brief Set dither bits for rendering.
 *
 * @param[in] page					Reference to a reflow page object. The page has to be parsed first.
 * @param[in] DitherBits			Default value: 2.
 *
 * @return	::kFGSErrorSuccess means successfully.<br>
 *			For more definitions please see enum definitions <b>FGSErrorRet</b>.
 */
FGSErrorRet FGSPDFReflowSetDitherBits(FGSPDFReflowPageRef page, SInt32 DitherBits);

/**
 * @brief Start rendering of a reflow page.
 *
 * @details Rendering is a progressive process. This function starts the rendering process,
 *			and may return before the rendering is finished, if a ::FS_PAUSE structure is provided.<br>
 *			Application should call ::FPDF_Reflow_ContinueRender repeatedly to finish the rendering 
 *			when the return value is ::FS_ERR_TOBECONTINUED.<br>
 *			There can be only one rendering procedure for a page at any time. And the rendering
 *			can be started over and over again for the same page. If a page rendering is already
 *			active, starting another one will cancel the previous rendering.<br>
 *			Rendering of a page doesn't draw the page background, therefore, you usually need
 *			to draw the background in the DIB yourself.
 *
 * @param[in] bitmapContext			Reference to a CGBitmapContext object, as the rendering device.
 * @param[in] page					Reference to a reflow page object. The page has to be parsed first.
 * @param[in] rect					The rect region of the display area in the device coordination (in pixel).
 * @param[in] rotate				The page orientation: 
 *									<ul>
 *									<li>0:	Normal</li>
 *									<li>1:	Rotate 90 degrees clockwise</li>
 *									<li>2:	Rotate 180 degrees</li>
 *									<li>3:	Rotate 90 degrees counter-clockwise</li>
 *									</ul>
 * @param[in] pause					A pointer to a ::FGSPause structure that can pause the rendering process.
 * 									Thsi can be <b>NULL</b> if no pausing is needed.
 *									If provided, this pointer has to be valid during the whole rendering.
 * @param[in] renderer	            Reference to a Receiving renderer object.
 *
 * @return	::kFGSErrorSuccess means rendering successfully finishes.<br>
 *			For more definitions please see enum definitions <b>FGSErrorRet</b>.
 */
FGSErrorRet FGSPDFReflowStartRenderingPage(CGContextRef bitmapContext, FGSPDFReflowPageRef page,  CGRect *rect, SInt32 rotate, FGSPause *pause, FGSDPRenderRef *renderer);

/**
 * @brief Start rendering of a reflow page.
 *
 * @param[in] bitmapContext			Reference to a CGBitmapContext object, as the rendering device.
 * @param[in] page					Reference to a reflow page object. The page has to be parsed first.
 * @param[in] matrix				The reflow page matrix of the device coordination.
 * @param[in] pause					pointer to a ::FGSPause structure that can pause the rendering process.
 * 									Thsi can be <b>NULL</b> if no pausing is needed.
 *									If provided, this pointer has to be valid during the whole rendering.
 * @param[in] renderer	            Reference to a Receiving renderer object.
 *
 * @return	::kFGSErrorSuccess means rendering successfully finishes.<br>
 *			For more definitions please see enum definitions <b>FGSErrorRet</b>.
 */
FGSErrorRet FGSPDFReflowStartRenderingPageEx(CGContextRef bitmapContext, FGSPDFReflowPageRef page, CGAffineTransform *matrix, FGSPause *pause, FGSDPRenderRef *renderer);

/**
 * @brief Continue rendering a reflow page.
 *
 * @param[in] renderer				Reference to a reflow page renderer object.
 *
 * @return	::kFGSErrorSuccess means rendering successfully finishes.<br>
 *			For more definitions please see enum definitions <b>FGSErrorRet</b>.
 *
 */
FGSErrorRet FGSPDFReflowContinueRenderingPage(FGSDPRenderRef renderer);

/**
 * @brief Stop rendering a reflow page.
 *
 * @param[in] renderer				Reference to a reflow page renderer object.
 *
 * @return	::kFGSErrorSuccess means rendering successfully finishes.<br>
 *			For more definitions please see enum definitions <b>FGSErrorRet</b>.
 *
 */
FGSErrorRet FGSPDFReflowStopRenderingPage(FGSDPRenderRef renderer);

/**
 * @brief Get the reflow page matrix.
 *
 * @param[in] page					Reference to a reflow page object. The page has to be parsed first.
 * @param[in] rect					The rect region of the display area in the device coordination.
 * @param[in] rotate				The page orientation: 
 *									<ul>
 *									<li>0:	Normal</li>
 *									<li>1:	Rotate 90 degrees clockwise</li>
 *									<li>2:	Rotate 180 degrees</li>
 *									<li>3:	Rotate 90 degrees counter-clockwise</li>
 *									</ul>
 *
 * @return	::kFGSErrorSuccess means get the data successfully.<br>
 *			For more definitions please see enum definitions <b>FGSErrorRet</b>.
*/
CGAffineTransform FGSPDFReflowGetPageDisplayingMatrix(FGSPDFReflowPageRef page, CGRect *rect, SInt32 rotate);

/**
 * @brief Get the data pointing to the current reading position
 *
 * @details This function retrieves the data pointing to the given reading position.
 *			Application can convert it to the physical position by calling ::FGSPDFReflowGetFocusPosition.
 *
 * @param[in] page					Reference to a page object.
 * @param[in] matrix                The matrix from ::FGSPDFReflowGetPageDisplayingMatrix.
 * @param[in] x						The value of the x-coordinate of the destination position
 * @param[in] y						The value of the y-coordinate of the destination position
 *
 * @return	a byte data of the destination data, user should release the data by calling <b>CFRelease</b>.
 */
CFDataRef FGSPDFReflowCopyFocusData(FGSPDFReflowPageRef page, const CGAffineTransform matrix, Float32 x, Float32 y);

/**
 * @brief Get a point pointing to the current reading position
 *
 * @details This function Get a point from data retrieved from ::FGSPDFReflowCopyFocusData.
 *
 * @param[in] page					Reference to a reflow page object.
 * @param[in] matrix                The matrix from ::FGSPDFReflowGetPageDisplayingMatrix.
 * @param[in] focusdata				Reference to the data returned by getFocusData.					
 *
 * @return	A PointF struct that receives the value of the destination position.
 *
 */
CGPoint FGSPDFReflowGetFocusPosition(FGSPDFReflowPageRef page, const CGAffineTransform matrix, CFDataRef focusdata);
    
#ifdef __cplusplus
};
#endif

#endif // __FGSPDFREFLOW__
/**@}*/


